package webapp.mvc.controllers;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.mustachejava.MustacheException;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.zoowii.formutils.BindingResult;
import com.zoowii.formutils.Validator;
import com.zoowii.jpa_utils.util.StringUtil;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxMenu;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage;
import me.chanjar.weixin.mp.bean.WxMpMassNews;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import webapp.mvc.components.HttpManager;
import webapp.mvc.components.SiteProperties;
import webapp.mvc.controllers.forms.*;
import webapp.mvc.enums.IntBooleans;
import webapp.mvc.exceptions.RedirectException;
import webapp.mvc.exceptions.UserException;
import webapp.mvc.models.CaptchaRequestEntity;
import webapp.mvc.models.UserEntity;
import webapp.mvc.models.WechatPushContentEntity;
import webapp.mvc.oss.IStoreService;
import webapp.mvc.oss.ObjectStoreInfo;
import webapp.mvc.services.ICaptchaService;
import webapp.mvc.services.ISiteConfigService;
import webapp.mvc.services.IUserService;
import webapp.mvc.wechat_handlers.WechatCategoriesHandler;
import webapp.mvc.wechat_handlers.WechatMyFavoritesHandler;
import webapp.mvc.wechat_handlers.WechatSubscribeHandler;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

@Controller
@RequestMapping("/")
public class HomeController {
    private static final Logger LOG = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    private IUserService userService;
    @Autowired
    private Validator validator;
    @Autowired
    private HttpManager httpManager;
    @Autowired
    private WxMpService wxMpService;
    @Autowired
    private WxMpConfigStorage wxMpConfigStorage;
    @Autowired
    private WxMpMessageRouter wxMpMessageRouter;
    @Autowired
    private WechatCategoriesHandler wechatCategoriesHandler;
    @Autowired
    private WechatMyFavoritesHandler wechatMyFavoritesHandler;
    @Autowired
    private WechatSubscribeHandler wechatSubscribeHandler;
    @Autowired
    private ICaptchaService captchaService;
    @Autowired
    private SiteProperties siteProperties;
    @Autowired
    private IStoreService storeService;
    @Autowired
    private ISiteConfigService siteConfigService;

    public static String WECHAT_AUTOLOGIN_KEY = "__wechat_openid";
    public static String WECHAT_OAUTH_KEY = "__wechat_oauth";

    private boolean wxRouterInited = false;

    private synchronized void initWxRouter() {
        if (wxRouterInited) {
            return;
        }
        wxRouterInited = true;
        wxMpMessageRouter
                .rule()
                .event(WxConsts.EVT_SUBSCRIBE)
                .handler(wechatSubscribeHandler)
                .end()
                .rule()
                .event(WxConsts.EVT_CLICK)
                .eventKey("categories")
                .handler(wechatCategoriesHandler)
                .end()
                .rule()
                .event(WxConsts.EVT_CLICK)
                .eventKey("my_favorites")
                .handler(wechatMyFavoritesHandler)
                .end();
    }

    @RequestMapping(value = "", method = RequestMethod.GET)
    public Object home(HttpServletRequest request, HttpServletResponse response, Model model) {
        try {
            httpManager.autoLoginOfWechat(request);
        } catch (RedirectException e) {
            return new RedirectView(e.getUrl());
        }
        initWxRouter();
        String username = (String) request.getSession(true).getAttribute("username");
        UserEntity userEntity = null;
        if (!StringUtil.isEmpty(username)) {
            userEntity = userService.findByUsername(username);
            if (userEntity != null) {
                userEntity.setRoles(userService.getRolesOfUser(userEntity.getId()));
            }
        }
        model.addAttribute("userInfo", userEntity != null ? ((JSONObject) JSON.toJSON(userEntity)).toJSONString() : "null");
        return "index";
    }

    @RequestMapping(value = "/my_favorites", method = RequestMethod.GET)
    public Object myFavoritesPage(HttpServletRequest request, HttpServletResponse response, Model model) {
        try {
            httpManager.autoLoginOfWechat(request);
        } catch (RedirectException e) {
            return new RedirectView(e.getUrl());
        }
        initWxRouter();
        String username = (String) request.getSession(true).getAttribute("username");
        UserEntity userEntity = null;
        if (!StringUtil.isEmpty(username)) {
            userEntity = userService.findByUsername(username);
            if (userEntity != null) {
                userEntity.setRoles(userService.getRolesOfUser(userEntity.getId()));
            }
        }
        model.addAttribute("userInfo", userEntity != null ? ((JSONObject) JSON.toJSON(userEntity)).toJSONString() : "null");
        return new RedirectView("/#/my_favorites");
    }

    @RequestMapping(value = "/categories", method = RequestMethod.GET)
    public Object categoriesPage(HttpServletRequest request, HttpServletResponse response, Model model) {
        try {
            httpManager.autoLoginOfWechat(request);
        } catch (RedirectException e) {
            return new RedirectView(e.getUrl());
        }
        initWxRouter();
        String username = (String) request.getSession(true).getAttribute("username");
        UserEntity userEntity = null;
        if (!StringUtil.isEmpty(username)) {
            userEntity = userService.findByUsername(username);
            if (userEntity != null) {
                userEntity.setRoles(userService.getRolesOfUser(userEntity.getId()));
            }
        }
        model.addAttribute("userInfo", userEntity != null ? ((JSONObject) JSON.toJSON(userEntity)).toJSONString() : "null");
        return new RedirectView("/#/categories");
    }

    @RequestMapping(value = "/hotest_shops/hotest", method = RequestMethod.GET)
    public Object hotestShopsPage(HttpServletRequest request, HttpServletResponse response, Model model) {
        try {
            httpManager.autoLoginOfWechat(request);
        } catch (RedirectException e) {
            return new RedirectView(e.getUrl());
        }
        initWxRouter();
        String username = (String) request.getSession(true).getAttribute("username");
        UserEntity userEntity = null;
        if (!StringUtil.isEmpty(username)) {
            userEntity = userService.findByUsername(username);
            if (userEntity != null) {
                userEntity.setRoles(userService.getRolesOfUser(userEntity.getId()));
            }
        }
        model.addAttribute("userInfo", userEntity != null ? ((JSONObject) JSON.toJSON(userEntity)).toJSONString() : "null");
        return new RedirectView("/#/hotest_shops/hotest");
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public
    @ResponseBody
    String login(HttpServletRequest request, LoginForm loginForm) {
        BindingResult bindingResult = validator.validate(loginForm);
        if (bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        try {
            HttpSession session = request.getSession(true);
            String captchaId = (String) session.getAttribute("captchaId");
            if (captchaId == null) {
                throw new UserException("需要输入正确的验证码");
            }
            CaptchaRequestEntity captchaRequestEntity = captchaService.findById(captchaId);
            if (captchaRequestEntity == null || !captchaRequestEntity.getAnswer().equalsIgnoreCase(loginForm.getCaptcha())) {
                // TODO: 验证码超时验证
                throw new UserException("验证码错误");
            }
            UserEntity userEntity = userService.checkUserAuth(loginForm.getUsername(), loginForm.getPassword());
            session.setAttribute("username", userEntity.getUsername());
            userEntity.setRoles(userService.getRolesOfUser(userEntity.getId()));
            return SimpleResponse.ok(userEntity).toJSON();
        } catch (UserException e) {
            LOG.error("check user auth error", e);
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public
    @ResponseBody
    String register(RegisterForm registerForm) {
        BindingResult bindingResult = validator.validate(registerForm);
        if (bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        try {
            UserEntity userEntity = userService.registerUser(registerForm);
            return SimpleResponse.ok(userEntity).toJSON();
        } catch (UserException e) {
            LOG.error("register user error", e);
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }

    @RequestMapping("/logout")
    public View logout(HttpServletRequest request) {
        request.getSession(true).removeAttribute("username");
        return new RedirectView("/");
    }

    @RequestMapping("/profile")
    public
    @ResponseBody
    Object profile(HttpServletRequest request, HttpServletResponse response) {
        try {
            httpManager.autoLoginOfWechat(request);
        } catch (RedirectException e) {
            return new RedirectView(e.getUrl());
        }
        userService.initRoles();
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        return SimpleResponse.ok(userEntity).toJSON();
    }

    @RequestMapping("/get_wechat_oauth_page_url")
    public
    @ResponseBody
    String getWechatOauthPageUrl() {
        String url = wxMpService.oauth2buildAuthorizationUrl(WxConsts.OAUTH2_SCOPE_BASE, null);
        return SimpleResponse.ok(url).toJSON();
    }

    @RequestMapping("/handle_wechat_oauth_code")
    public Object handleWechatOAuthCode(HttpServletRequest request) {
        initWxRouter();
        String code = request.getParameter("code");

        try {
            WxMpOAuth2AccessToken wxMpOAuth2AccessToken = null;
            int triedFetchAccessTokenCount = 0;
            do {
                try {
                    wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
                    LOG.info("got oauth2 access token " + wxMpOAuth2AccessToken.getAccessToken());
                    if (!wxMpService.oauth2validateAccessToken(wxMpOAuth2AccessToken)) {
                        wxMpOAuth2AccessToken = wxMpService.oauth2refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken());
                        LOG.info("get oauth2 " + wxMpOAuth2AccessToken.getOpenId());
                    } else {
                        LOG.info("get oauth2 failed " + wxMpOAuth2AccessToken.getOpenId());
                    }
                    break;
                } catch (Exception e) {
                    triedFetchAccessTokenCount += 1;
                }
            } while (triedFetchAccessTokenCount < 10);
            if (wxMpOAuth2AccessToken == null) {
                return SimpleResponse.fail("获取access token失败").toJSON();
            }
            HttpSession session = request.getSession(true);
            session.setAttribute("wechatAccessToken", wxMpOAuth2AccessToken);
            String openId = wxMpOAuth2AccessToken.getOpenId();
            UserEntity userEntity = userService.findOrCreateUserByWechatOpenId(wxMpService, openId);
//            WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
//            // 检查此微信用户是否已经有对应用户，没有自动创建并自动登陆，已经有了就直接自动登陆
//            UserEntity userEntity = userService.findUserByWechatOpenId(wxMpUser.getOpenId());
//            if (userEntity == null) {
//                userEntity = userService.createWechatUserBinding(wxMpUser.getOpenId(), wxMpUser.getNickname(), wxMpUser.getSexId(), null);
//            }
            LOG.info(userEntity.getDisplayName());
            session.setAttribute("username", userEntity.getUsername());
            String redirectUrl = request.getParameter("redirect");
            if (StringUtil.isEmpty(redirectUrl)) {
                redirectUrl = siteProperties.getHost() + "/";
            } else {
                redirectUrl = siteProperties.getHost() + "/#" + redirectUrl;
            }
            LOG.info("redirect to " + redirectUrl );
            return new RedirectView(redirectUrl);
        } catch (UserException e) {
            LOG.error("get wechat access token error", e);
//            return SimpleResponse.fail(e.getMessage()).toJSON();
            return new RedirectView(request.getRequestURI());
        }
    }

    @RequestMapping("/create_wechat_menu")
    public
    @ResponseBody
    String createWechatMenu() {
        initWxRouter();
        WxMenu wxMenu = new WxMenu();
        WxMenu.WxMenuButton indexBtn = new WxMenu.WxMenuButton();
        indexBtn.setType(WxConsts.BUTTON_VIEW);
        indexBtn.setName("首页");
        indexBtn.setUrl(siteProperties.getHost() + "/?" + WECHAT_OAUTH_KEY + "=" + "/");
        WxMenu.WxMenuButton viewShopsButton = new WxMenu.WxMenuButton();
        viewShopsButton.setName("商户");
        viewShopsButton.setType(WxConsts.BUTTON_VIEW);
        viewShopsButton.setUrl(siteProperties.getHost() + "/categories?" + WECHAT_OAUTH_KEY + "=/categories");
        WxMenu.WxMenuButton hotestShopsBtn = new WxMenu.WxMenuButton();
        hotestShopsBtn.setName("热门商户");
        hotestShopsBtn.setType(WxConsts.BUTTON_VIEW);
        hotestShopsBtn.setUrl(siteProperties.getHost() + "/hotest_shops/hotest?" + WECHAT_OAUTH_KEY + "=/hotest_shops/hotest");
        WxMenu.WxMenuButton shopsBtn = new WxMenu.WxMenuButton();
        shopsBtn.setName("店铺优惠");
        shopsBtn.setSubButtons(Arrays.asList(indexBtn, viewShopsButton, hotestShopsBtn));
        WxMenu.WxMenuButton myFavarShopsButton = new WxMenu.WxMenuButton();
        myFavarShopsButton.setName("收藏你好");
        myFavarShopsButton.setType(WxConsts.BUTTON_VIEW);
        myFavarShopsButton.setUrl(siteProperties.getHost() + "/my_favorites?" + WECHAT_OAUTH_KEY + "=/my_favorites");
        WxMenu.WxMenuButton othersButton = new WxMenu.WxMenuButton();
        othersButton.setName("其他");
        WxMenu.WxMenuButton oneCardAboutBtn = new WxMenu.WxMenuButton();
        oneCardAboutBtn.setName("一卡通介绍");
        oneCardAboutBtn.setType(WxConsts.BUTTON_VIEW);
        oneCardAboutBtn.setUrl(siteProperties.getHost() + "/help_phone_page");
        WxMenu.WxMenuButton renewAboutBtn = new WxMenu.WxMenuButton();
        renewAboutBtn.setName("补办说明");
        renewAboutBtn.setType(WxConsts.BUTTON_VIEW);
        renewAboutBtn.setUrl(siteProperties.getHost() + "/renew_about_page");
        WxMenu.WxMenuButton helpPhoneBtn = new WxMenu.WxMenuButton();
        helpPhoneBtn.setName("咨询电话");
        helpPhoneBtn.setType(WxConsts.BUTTON_VIEW);
        helpPhoneBtn.setUrl(siteProperties.getHost() + "/help_phone_page");
        othersButton.setSubButtons(Arrays.asList(oneCardAboutBtn, renewAboutBtn, helpPhoneBtn));
        wxMenu.setButtons(Arrays.asList(shopsBtn, myFavarShopsButton, othersButton));
        try {
            wxMpService.menuCreate(wxMenu);
            return SimpleResponse.ok(wxMenu).toJSON();
        } catch (WxErrorException e) {
            LOG.error("wechat menu create error", e);
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }

    @RequestMapping(value = "/wechat_api_handler", method = {RequestMethod.POST, RequestMethod.GET})
    public void handleWeixinApi(HttpServletRequest request, HttpServletResponse response) throws IOException {
        initWxRouter();
        String signature = request.getParameter("signature");
        String nonce = request.getParameter("nonce");
        String timestamp = request.getParameter("timestamp");

        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);

        if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
            // 消息签名不正确，说明不是公众平台发过来的消息
            response.getWriter().println("非法请求");
            return;
        }

        String echostr = request.getParameter("echostr");
        if (!StringUtil.isEmpty(echostr)) {
            // 说明是一个仅仅用来验证的请求，回显echostr
            response.getWriter().println(echostr);
            return;
        }

        String encryptType = StringUtil.isEmpty(request.getParameter("encrypt_type")) ?
                "raw" :
                request.getParameter("encrypt_type");

        WxMpXmlMessage inMessage = null;

        if ("raw".equals(encryptType)) {
            // 明文传输的消息
            inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
        } else if ("aes".equals(encryptType)) {
            // 是aes加密的消息
            String msgSignature = request.getParameter("msg_signature");
            inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), wxMpConfigStorage, timestamp, nonce, msgSignature);
        } else {
            response.getWriter().println("不可识别的加密类型");
            return;
        }
        WxMpMessageHandler wxMpMessageHandler;
        WxMpXmlOutMessage outMessage = null;
        if ("categories".equals(inMessage.getEventKey())) {
            wxMpMessageHandler = wechatCategoriesHandler;
        } else if ("my_favorites".equals(inMessage.getEventKey())) {
            wxMpMessageHandler = wechatMyFavoritesHandler;
        } else {
            response.getWriter().write("Can't find message handler for event key" + inMessage.getEventKey());
            return;
        }
        try {
            outMessage = wxMpMessageHandler.handle(inMessage, null, wxMpService, null);
        } catch (WxErrorException e) {
            LOG.error("wechat handler error", e);
        }
//        outMessage = wxMpMessageRouter.route(inMessage);

        if (outMessage != null) {
            if ("raw".equals(encryptType)) {
                response.getWriter().write(outMessage.toXml());
            } else if ("aes".equals(encryptType)) {
                response.getWriter().write(outMessage.toEncryptedXml(wxMpConfigStorage));
            }
            return;
        }
    }

    @RequestMapping(value = "/create_wechat_push", method = RequestMethod.POST)
    public
    @ResponseBody
    String createWechatPushContent(HttpServletRequest request, WechatPushForm wechatPushForm) {
        JSONArray articlesJson = wechatPushForm.getContentJsonArray();
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        try {
            WechatPushContentEntity wechatPushContentEntity = userService.saveWechatPushContent(wechatPushForm.getContentId(), wechatPushForm.getTitle(), articlesJson.toJSONString());
            if (wechatPushForm.isPush()) {
                pushWechatGroupNews(request, wechatPushContentEntity, userEntity.getId());
            }
            return SimpleResponse.ok(wechatPushContentEntity).toJSON();
//            return SimpleResponse.ok("test").toJSON();
        } catch (Exception e) {
            LOG.error("wechat push error", e);
            return SimpleResponse.error(e).toJSON();
        }
    }

    @RequestMapping(value = "/push_wechat_group_news/{contentId}", method = RequestMethod.POST)
    public
    @ResponseBody
    String pushGroupNews(HttpServletRequest request, @PathVariable String contentId) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        WechatPushContentEntity wechatPushContentEntity = userService.findWechatPushContentById(contentId);
        if (wechatPushContentEntity == null) {
            return SimpleResponse.fail("找不到此微信图文消息").toJSON();
        }
        try {
            return SimpleResponse.ok(pushWechatGroupNews(request, wechatPushContentEntity, userEntity.getId())).toJSON();
        } catch (Exception e) {
            LOG.error("push wechat news error", e);
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }

    private WxMpMassSendResult pushWechatGroupNews(HttpServletRequest request, WechatPushContentEntity wechatPushContentEntity, String userId) throws WxErrorException, IOException, UnirestException {
        WxMpMassNews news = new WxMpMassNews();
        JSONArray articlesJson = JSONArray.parseArray(wechatPushContentEntity.getContent());
        for (int i = 0; i < articlesJson.size(); ++i) {
            JSONObject articleJson = articlesJson.getJSONObject(i);
            if (StringUtil.isEmpty(articleJson.getString("title"))
                    || StringUtil.isEmpty(articleJson.getString("content"))
                    || StringUtil.isEmpty(articleJson.getString("mediaFileId"))) {
                continue;
            }
            WxMpMassNews.WxMpMassNewsArticle article = new WxMpMassNews.WxMpMassNewsArticle();
            article.setContent(articleJson.getString("content"));
            article.setTitle(articleJson.getString("title"));
            article.setAuthor(articleJson.getString("author"));
            String mediaFileId = articleJson.getString("mediaFileId");
            String mediaFileUrl = storeService.getFile(request, mediaFileId, mediaFileId);
            InputStream mediaFileInputStream = Unirest.get(mediaFileUrl).asBinary().getRawBody();
            try {
                WxMediaUploadResult uploadMediaRes = wxMpService.mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, mediaFileInputStream);
                article.setThumbMediaId(uploadMediaRes.getMediaId());
                news.addArticle(article);
            } finally {
                mediaFileInputStream.close();
            }
        }
        WxMpMassUploadResult massUploadResult = wxMpService.massNewsUpload(news);
        WxMpMassGroupMessage wxMpMassGroupMessage = new WxMpMassGroupMessage();
        wxMpMassGroupMessage.setMediaId(massUploadResult.getMediaId());
        wxMpMassGroupMessage.setMsgtype(WxConsts.MASS_MSG_NEWS);
        WxMpMassSendResult wxMpMassSendResult = wxMpService.massGroupMessageSend(wxMpMassGroupMessage);
        userService.saveWechatPushHistory(wechatPushContentEntity.getId(), userId);
        if (wechatPushContentEntity.getPushed() == IntBooleans.FALSE) {
            wechatPushContentEntity.setPushed(IntBooleans.TRUE);
            wechatPushContentEntity.update();
        }
        return wxMpMassSendResult;
    }

    /**
     * 微信的群发消息
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/wechat_push", method = RequestMethod.POST)
    public
    @ResponseBody
    String pushToAllWechatUsers(HttpServletRequest request, WechatPushForm wechatPushForm) {
        JSONArray articlesJson = wechatPushForm.getContentJsonArray();
        WxMpMassNews news = new WxMpMassNews();
        try {
            for (int i = 0; i < articlesJson.size(); ++i) {
                JSONObject articleJson = articlesJson.getJSONObject(i);
                if (StringUtil.isEmpty(articleJson.getString("title"))
                        || StringUtil.isEmpty(articleJson.getString("content"))
                        || StringUtil.isEmpty(articleJson.getString("mediaFileId"))) {
                    continue;
                }
                WxMpMassNews.WxMpMassNewsArticle article = new WxMpMassNews.WxMpMassNewsArticle();
                article.setContent(articleJson.getString("content"));
                article.setTitle(articleJson.getString("title"));
                article.setAuthor(articleJson.getString("author"));
                String mediaFileId = articleJson.getString("mediaFileId");
                String mediaFileUrl = storeService.getFile(request, mediaFileId, mediaFileId);
                InputStream mediaFileInputStream = Unirest.get(mediaFileUrl).asBinary().getRawBody();
                try {
                    WxMediaUploadResult uploadMediaRes = wxMpService.mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, mediaFileInputStream);
                    article.setThumbMediaId(uploadMediaRes.getMediaId());
                    news.addArticle(article);
                } finally {
                    mediaFileInputStream.close();
                }
            }
            WxMpMassUploadResult massUploadResult = wxMpService.massNewsUpload(news);
            WxMpMassGroupMessage wxMpMassGroupMessage = new WxMpMassGroupMessage();
            wxMpMassGroupMessage.setMediaId(massUploadResult.getMediaId());
            wxMpMassGroupMessage.setMsgtype(WxConsts.MASS_MSG_NEWS);
            WxMpMassSendResult massSendResult = wxMpService.massGroupMessageSend(wxMpMassGroupMessage);
            userService.saveWechatPushContent(null, wechatPushForm.getTitle(), articlesJson.toJSONString());
            return SimpleResponse.ok(massSendResult).toJSON();
//            return SimpleResponse.ok("test").toJSON();
        } catch (Exception e) {
            LOG.error("wechat push error", e);
            return SimpleResponse.error(e).toJSON();
        }
    }

    @RequestMapping(value = "/ueditor_upload", method = {RequestMethod.POST, RequestMethod.GET})
    public void ueditorUpload(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "upfile", required = false) CommonsMultipartFile file) {
        try {
            request.setCharacterEncoding("utf-8");
            if ("config".equals(request.getParameter("action"))) {
                InputStream configInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("ueditor.config.json");
                response.setCharacterEncoding("utf-8");
                response.setHeader("Content-Type", "text/plain");
                IOUtils.copy(configInputStream, response.getOutputStream());
                return;
            }
            if ("uploadimage".equals(request.getParameter("action"))) {
                String filename = file.getOriginalFilename();
                try {
                    ObjectStoreInfo objectStoreInfo = storeService.putFile(file.getInputStream(), filename);
                    JSONObject resJson = new JSONObject();
                    resJson.put("state", "SUCCESS");
                    resJson.put("url", siteProperties.getHost() + "/file/view_direct/" + objectStoreInfo.getKey());
                    resJson.put("title", filename);
                    resJson.put("original", filename);
                    response.getWriter().write(resJson.toJSONString());
                    return;
                } catch (Exception e) {
                    LOG.error("store file error", e);
                    response.getWriter().write(e.getMessage());
                    return;
                }
            }
            response.setHeader("Content-Type", "text/html");
            response.getWriter().write("not support action");
        } catch (Exception e) {
            LOG.error("ueditor upload error", e);
        }
    }

    @RequestMapping("/config/{configKey}")
    public
    @ResponseBody
    String getConfig(@PathVariable String configKey) {
        String value = siteConfigService.get(configKey);
        if (value != null) {
            return SimpleResponse.ok(value).toJSON();
        } else {
            return SimpleResponse.fail(false).toJSON();
        }
    }

    @RequestMapping(value = "/set_config", method = RequestMethod.POST)
    public
    @ResponseBody
    String setConfig(SetConfigForm setConfigForm) {
        if (StringUtil.isEmpty(setConfigForm.getKey())
                || StringUtil.isEmpty(setConfigForm.getValue())) {
            return SimpleResponse.fail("配置不可为空").toJSON();
        }
        siteConfigService.set(setConfigForm.getKey(), setConfigForm.getValue());
        return SimpleResponse.ok(siteConfigService.get(setConfigForm.getKey())).toJSON();
    }

    @RequestMapping("/help_phone_page")
    public void helpPhonePage(HttpServletRequest request, HttpServletResponse response) {
        String content = siteConfigService.get("help_phone_page_content");
        if (content == null) {
            content = "";
        }
        content = "<!DOCTYPE html><html><head><meta charset='utf-8'><title>咨询电话</title></head><body>" + content + "</body></html>";
        try {
            response.getWriter().write(content);
        } catch (IOException e) {
            LOG.error("io error", e);
        }
    }

    @RequestMapping("/renew_about_page")
    public void renewAboutPage(HttpServletRequest request, HttpServletResponse response) {
        String content = siteConfigService.get("renew_about_page_content");
        if (content == null) {
            content = "";
        }
        content = "<!DOCTYPE html><html><head><meta charset='utf-8'><title>补办说明</title></head><body>" + content + "</body></html>";
        try {
            response.getWriter().write(content);
        } catch (IOException e) {
            LOG.error("io error", e);
        }
    }

    @RequestMapping("/one_card_about_page")
    public void oneCardAboutPage(HttpServletRequest request, HttpServletResponse response) {
        String content = siteConfigService.get("one_card_about_page_content");
        if (content == null) {
            content = "";
        }
        content = "<!DOCTYPE html><html><head><meta charset='utf-8'><title>一卡通介绍</title></head><body>" + content + "</body></html>";
        try {
            response.getWriter().write(content);
        } catch (IOException e) {
            LOG.error("io error", e);
        }
    }

    @RequestMapping("/test_template_error")
    public String testTemplateError() {
        return "test_template_error";
    }

    @ExceptionHandler(MustacheException.class)
    public void weichatErrorHandler(HttpServletRequest request, HttpServletResponse response) {
        LOG.error("got mustache error, maybe wechat error");
        try {
            response.getWriter().write("<script>window.location.href='/';</script>");
        } catch (IOException e) {
            LOG.error("io error", e);
        }
    }
}
